<template>
  <div ref="container" class="celebration-container"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

const props = defineProps({
  duration: {
    type: Number,
    default: 5000 // 动画持续时间
  },
  particleCount: {
    type: Number,
    default: 500 // 彩带数量
  },
  ribbonWidth: {
    type: Number,
    default: 3 // 彩带宽度
  },
  ribbonLength: {
    type: Number,
    default: 10 // 彩带长度
  },
  opacity: {
    type: Number,
    default: 0.9 // 不透明度
  },
  windStrength: {
    type: Number,
    default: 1.0 // 风力强度
  }
});

const emit = defineEmits(['animationEnd']);

const container = ref<HTMLElement>();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 2000);
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true
});
let ribbonGroup: THREE.Group;
let controls: OrbitControls;
let animationId: number;
let windDirection = 0; // 风向角度
let windSpeed = 0; // 风速

// 更丰富的彩带配色方案
const colorPalette = [
  new THREE.Color(0xFF3366), // 亮粉
  new THREE.Color(0xFFCC00), // 亮黄
  new THREE.Color(0x33CCFF), // 亮蓝
  new THREE.Color(0x33CC33), // 亮绿
  new THREE.Color(0xFF6600), // 橙色
  new THREE.Color(0x9966FF), // 紫色
  new THREE.Color(0xFF0000), // 红色
  new THREE.Color(0x0066FF), // 蓝色
  new THREE.Color(0xFF9900), // 琥珀色
  new THREE.Color(0x00CC99), // 青绿色
  new THREE.Color(0xFF66B3), // 粉色
  new THREE.Color(0xCC99FF), // 淡紫色
];

// 创建更自然的彩带几何体
function createRibbonGeometry(segments: number = 20) {
  const geometry = new THREE.PlaneGeometry(
    props.ribbonWidth,
    props.ribbonLength,
    1,
    segments
  );
  
  // 添加自然弯曲和不规则形状
  const vertices = geometry.attributes.position.array;
  for (let i = 0; i < vertices.length; i += 3) {
    const segment = Math.floor(i / 3 / (segments + 1));
    const progress = segment / segments;
    
    // 沿长度方向的自然弯曲
    const curveX = Math.sin(progress * Math.PI) * (0.2 + Math.random() * 0.1) * props.ribbonWidth;
    vertices[i] += curveX;
    
    // 随机波动，使每条彩带略有不同
    vertices[i + 2] = (Math.random() - 0.5) * 8 * (1 - progress * 0.5); // 尾部更灵活
    
    // 随机边缘波浪
    if (i % (segments + 1) === 0 || i % (segments + 1) === segments) {
      const wave = Math.sin(progress * Math.PI * 5) * (Math.random() * 2 + 1);
      vertices[i + 1] += wave;
    }
  }
  
  return geometry;
}

// 创建更逼真的彩带材质
function createRibbonMaterial(color: THREE.Color) {
  return new THREE.MeshBasicMaterial({
    color,
    side: THREE.DoubleSide,
    transparent: true,
    opacity: props.opacity,
    // 添加一些反射效果，模拟真实彩带的光泽
    // emissive: color.clone().multiplyScalar(0.3),
  });
}

// 初始化场景
function initScene() {
  if (!container.value) return;

  camera.position.z = 600;
  camera.position.y = 100;
  camera.lookAt(0, 0, 0);
  
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  container.value.appendChild(renderer.domElement);

  // 调试控制器
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableZoom = false;

  createRibbons();
  renderer.domElement.style.display = 'none';
}

// 创建彩带系统
function createRibbons() {
  ribbonGroup = new THREE.Group();
  scene.add(ribbonGroup);

  // 创建多个彩带
  for (let i = 0; i < props.particleCount; i++) {
    const ribbonGeometry = createRibbonGeometry(25);
    const color = colorPalette[Math.floor(Math.random() * colorPalette.length)];
    const material = createRibbonMaterial(color);

    const ribbon = new THREE.Mesh(ribbonGeometry, material);
    
    // 随机初始位置和状态
    resetRibbon(ribbon);
    
    ribbonGroup.add(ribbon);
  }

  // 添加环境光
  const ambientLight = new THREE.AmbientLight(0xffffff, 1.2);
  scene.add(ambientLight);
}

// 重置彩带位置和状态
function resetRibbon(ribbon: THREE.Mesh) {
  const { innerWidth, innerHeight } = window;
  
  // 随机x位置（全屏范围）
  ribbon.position.x = (Math.random() - 0.5) * innerWidth * 1.2;
  // 从屏幕顶部外开始
  ribbon.position.y = innerHeight / 2 + Math.random() * innerHeight / 3;
  // z轴位置创造层次感
  ribbon.position.z = -300 + Math.random() * 600;
  
  // 随机旋转（让彩带以不同角度开始下落）
  ribbon.rotation.x = Math.random() * Math.PI * 0.2 - Math.PI * 0.1; // 略微前倾
  ribbon.rotation.y = Math.random() * Math.PI;
  ribbon.rotation.z = Math.random() * Math.PI * 0.3 - Math.PI * 0.15;
  
  // 存储物理属性
  (ribbon as any).fallSpeed = 3 + Math.random() * 8; // 下落速度
  (ribbon as any).rotationSpeed = (Math.random() - 0.5) * 0.015; // 旋转速度
  (ribbon as any).sway = Math.random() * Math.PI * 2; // 摆动相位
  (ribbon as any).swaySpeed = 0.008 + Math.random() * 0.012; // 摆动速度
  (ribbon as any).flap = Math.random() * Math.PI; // 翻动相位
  (ribbon as any).flapSpeed = 0.005 + Math.random() * 0.01; // 翻动速度
  (ribbon as any).mass = 0.7 + Math.random() * 0.6; // 质量影响物理表现
  (ribbon as any).drag = 0.98 + Math.random() * 0.02; // 空气阻力
  (ribbon as any).windResistance = 0.3 + Math.random() * 0.7; // 受风阻力
  (ribbon as any).turbulence = Math.random() * 0.03; // 湍流影响
  
  // 记录原始几何体，用于恢复形状
  (ribbon as any).originalVertices = [...ribbon.geometry.attributes.position.array];
}

// 启动动画
function startAnimation() {
  if (!container.value) return;

  renderer.domElement.style.display = 'block';
  
  // 重置所有彩带
  ribbonGroup.children.forEach(ribbon => {
    resetRibbon(ribbon as THREE.Mesh);
  });

  const startTime = Date.now();

  function animate() {
    animationId = requestAnimationFrame(animate);
    
    const elapsed = Date.now() - startTime;
    const progress = Math.min(elapsed / props.duration, 1);
    
    // 动态变化的风场模拟
    updateWind(elapsed);
    
    // 更新所有彩带
    updateRibbons(progress);
    
    if (progress >= 1) {
      renderer.domElement.style.display = 'none';
      emit('animationEnd');
      return;
    }

    renderer.render(scene, camera);
  }

  animate();
}

// 更新风力和风向
function updateWind(elapsed: number) {
  // 缓慢变化的主风向
  windDirection = (elapsed * 0.00005) % (Math.PI * 2);
  
  // 风速波动
  windSpeed = Math.sin(elapsed * 0.0003) * 0.3 + 
              Math.sin(elapsed * 0.0001) * 0.5 + 
              props.windStrength;
}

// 更新彩带动画
function updateRibbons(progress: number) {
  const { innerHeight } = window;
  const windX = Math.cos(windDirection) * windSpeed;
  const windY = Math.sin(windDirection) * windSpeed * 0.3; // 垂直风力较小
  
  ribbonGroup.children.forEach((ribbon: THREE.Mesh) => {
    const ribbonData = ribbon as any;

    ribbonData.fallSpeed += windY * 0.1;
    ribbon.position.x += windX * ribbonData.windResistance;

    // 下落运动
    ribbon.position.y -= ribbonData.fallSpeed * ribbonData.mass;
    
    // 随机湍流
    ribbon.position.x += (Math.random() - 0.5) * ribbonData.turbulence;
    ribbon.position.y += (Math.random() - 0.5) * ribbonData.turbulence * 0.3;
    
    // 自然摆动
    ribbon.position.x += Math.sin(ribbonData.sway) * 0.8 * ribbonData.mass;
    ribbonData.sway += ribbonData.swaySpeed;
    
    // 彩带翻动效果（绕x轴）
    ribbon.rotation.x = Math.sin(ribbonData.flap) * 0.4 + Math.random() * 0.1;
    ribbonData.flap += ribbonData.flapSpeed;
    
    // 旋转（绕z轴）
    ribbon.rotation.z += ribbonData.rotationSpeed;
    
    // 彩带飘动变形效果
    deformRibbon(ribbon, ribbonData);
    
    // 当彩带落到屏幕底部外，重置到顶部
    if (ribbon.position.y < -innerHeight / 2 - 150) {
      resetRibbon(ribbon);
    }
    
    // 轻微减速，模拟空气阻力
    ribbonData.fallSpeed *= ribbonData.drag;
    ribbonData.fallSpeed = Math.max(ribbonData.fallSpeed, 2); // 确保有最小速度
  });
}

// 使彩带自然变形
function deformRibbon(ribbon: THREE.Mesh, ribbonData: any) {
  const vertices = ribbon.geometry.attributes.position.array;
  const originalVertices = ribbonData.originalVertices;
  const segments = vertices.length / 3 - 1;
  
  for (let i = 0; i < vertices.length; i += 3) {
    const segment = Math.floor(i / 3 / (segments + 1));
    const progress = segment / segments;
    
    // 基于风力和位置的变形
    const windEffectX = Math.sin(ribbonData.sway + progress * 2) * windSpeed * 2 * (1 - progress);
    const windEffectZ = Math.cos(ribbonData.sway + progress * 3) * windSpeed * 1.5 * (1 - progress);
    
    // 恢复原始形状加上变形
    vertices[i] = originalVertices[i] + windEffectX;
    vertices[i + 2] = originalVertices[i + 2] + windEffectZ;
  }
  
  // 标记几何体需要更新
  ribbon.geometry.attributes.position.needsUpdate = true;
}

// 窗口大小变化处理
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

// 暴露启动方法
defineExpose({
  start: startAnimation
});

onMounted(() => {
  initScene();
  window.addEventListener('resize', onWindowResize);
});

onUnmounted(() => {
  cancelAnimationFrame(animationId);
  window.removeEventListener('resize', onWindowResize);
  if (container.value?.contains(renderer.domElement)) {
    container.value.removeChild(renderer.domElement);
  }
});
</script>

<style scoped>
.celebration-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 100;
  overflow: hidden;
}
</style>